home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / gui / pastbrowser.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  18KB  |  476 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. import wx
  6. from gui import skin
  7. from gui.uberwidgets.PrefPanel import PrefPanel
  8. from gui.uberwidgets.UberCombo import UberCombo
  9. from gui.uberwidgets.simplemenu import SimpleMenuItem
  10. from gui.uberwidgets.UberButton import UberButton
  11. from gui.toolbox import persist_window_pos, snap_pref
  12. from gui.browser.webkit import WebKitWindow
  13. from cgui import SimplePanel
  14. from util import Storage
  15. from common import logger
  16. import logging
  17. log = logging.getLogger('pastbrowser')
  18. from wx import ALL, TOP, BOTTOM, LEFT, EXPAND, ALIGN_CENTER_VERTICAL, ALIGN_LEFT, ALIGN_RIGHT, VERTICAL, HORIZONTAL, WHITE, WHITE_BRUSH, TRANSPARENT_PEN, Color, BoxSizer, Brush, Rect
  19. TOPLESS = ALL & ~TOP
  20. BUTTON_SKIN = 'AppDefaults.PastButton'
  21. from wx import DateTimeFromDMY
  22. from wx.calendar import CAL_SUNDAY_FIRST, CAL_SEQUENTIAL_MONTH_SELECTION, CAL_SHOW_HOLIDAYS, EVT_CALENDAR_MONTH, EVT_CALENDAR_YEAR, EVT_CALENDAR_SEL_CHANGED, CalendarCtrl, CalendarDateAttr
  23.  
  24. def logpath_for_date(buddy, date):
  25.     year = '%d' % int(date.GetYear())
  26.     month = '%02d' % (date.GetMonth() + 1)
  27.     day = '%02d' % int(date.GetDay())
  28.     return buddy.dir / ''.join([
  29.         year,
  30.         '-',
  31.         month,
  32.         '-',
  33.         day,
  34.         '.html'])
  35.  
  36.  
  37. def MakeAccountItems():
  38.     logdir = logger.get_default_logging_dir()
  39.     protodirs = logdir.dirs()
  40.     accts = { }
  41.     for protodir in protodirs:
  42.         accts[protodir.name] = [ dir.name for dir in protodir.dirs() ]
  43.     
  44.     items = []
  45.     for proto in accts:
  46.         
  47.         try:
  48.             protoicon = skin.get('serviceicons.' + proto, None).ResizedSmaller(16)
  49.         except Exception:
  50.             []
  51.             []
  52.             []
  53.             continue
  54.         except:
  55.             []
  56.  
  57.         for acct in accts[proto]:
  58.             items.append(SimpleMenuItem([
  59.                 protoicon,
  60.                 acct], id = logdir / proto / acct))
  61.         
  62.     
  63.     return items
  64.  
  65.  
  66. def GetBuddies(acctdir):
  67.     buddies = []
  68.     for bdir in acctdir.dirs():
  69.         
  70.         try:
  71.             (name, service) = bdir.name.rsplit('_', 1)
  72.             serviceicon = skin.get('serviceicons.' + service, None).ResizedSmaller(16)
  73.         except Exception:
  74.             continue
  75.  
  76.         buddies.append(Storage(icon = serviceicon, name = name, service = service, dir = bdir))
  77.     
  78.     return buddies
  79.  
  80.  
  81. def GetDates(logdir):
  82.     dates = []
  83.     append = dates.append
  84.     for logfile in logdir.files():
  85.         datestring = logfile.name
  86.         
  87.         try:
  88.             (y, m, d) = datestring[:datestring.rfind('.')].split('-')
  89.             y = int(y)
  90.             m = int(m) - 1
  91.             d = int(d)
  92.         except Exception:
  93.             continue
  94.  
  95.         append(DateTimeFromDMY(d, m, y))
  96.     
  97.     return sorted(dates)
  98.  
  99. bgcolors = [
  100.     wx.Color(239, 239, 239),
  101.     wx.Color(255, 255, 255)]
  102. hovbgcolor = wx.Color(220, 220, 220)
  103.  
  104. def SelectAccountByDir(acctdir, combo):
  105.     for item in combo:
  106.         if acctdir == item.id:
  107.             combo.SetSelection(combo.GetIndex(item))
  108.             return True
  109.             continue
  110.     
  111.     return False
  112.  
  113.  
  114. class ListOBuddies(wx.VListBox):
  115.     
  116.     def __init__(self, parent):
  117.         wx.VListBox.__init__(self, parent, -1)
  118.         self.buddies = []
  119.         self.Hovered = -1
  120.         self.SetItemCount(0)
  121.         self.itemheight = max(self.Font.Height, 16) + 10
  122.         self.date = None
  123.         Bind = self.Bind
  124.         Bind(wx.EVT_MOTION, self.OnMotion)
  125.  
  126.     
  127.     def OnMotion(self, event):
  128.         rect = self.ClientRect
  129.         wap = wx.FindWindowAtPointer()
  130.         mp = event.Position
  131.         hit = self.HitTest(mp)
  132.         if not rect.Contains(mp) or not (wap == self):
  133.             while self.HasCapture():
  134.                 self.ReleaseMouse()
  135.             self.Hovered = -1
  136.             self.Refresh()
  137.             return None
  138.         elif not self.HasCapture():
  139.             self.CaptureMouse()
  140.         
  141.         self.Hovered = hit
  142.         self.Refresh()
  143.  
  144.     
  145.     def OnDrawBackground(self, dc, rect, n):
  146.         if self.Selection == n:
  147.             dc.Brush = Brush(wx.SystemSettings_GetColour(wx.SYS_COLOUR_HIGHLIGHT))
  148.         elif self.Hovered == n:
  149.             pass
  150.         
  151.         dc.Brush = Brush(bgcolors[n % len(bgcolors)])
  152.         dc.Pen = wx.TRANSPARENT_PEN
  153.         dc.DrawRectangleRect(rect)
  154.  
  155.     
  156.     def OnDrawItem(self, dc, rect, n):
  157.         dc.Font = self.Font
  158.         dc.TextForeground = None if self.Selection == n else wx.BLACK
  159.         buddy = self.buddies[n]
  160.         x = rect.x + 3
  161.         y = rect.y + rect.height // 2 - 8
  162.         dc.DrawBitmap(buddy.icon, x, y, True)
  163.         textrect = Rect(x + 16 + 3, rect.y, rect.Width - x - 38, rect.Height)
  164.         dc.DrawLabel(buddy.name, textrect, ALIGN_CENTER_VERTICAL | ALIGN_LEFT)
  165.  
  166.     
  167.     def OnMeasureItem(self, n):
  168.         return self.itemheight
  169.  
  170.     
  171.     def SetList(self, buddies):
  172.         self.buddies = buddies
  173.         self.SetItemCount(len(self.buddies))
  174.         if self.ItemCount:
  175.             self.SetSelection(0)
  176.         
  177.         wx.CallAfter(self.Refresh)
  178.  
  179.     
  180.     def SelectedBuddy(self):
  181.         return self.buddies[self.Selection]
  182.  
  183.     SelectedBuddy = property(SelectedBuddy)
  184.     
  185.     def SelectBuddy(self, service, name):
  186.         found = -1
  187.         for i, buddy in enumerate(self.buddies):
  188.             if buddy.name == name and buddy.service == service:
  189.                 found = i
  190.                 break
  191.                 continue
  192.         
  193.         self.Selection = found
  194.         if found != -1:
  195.             self.ProcessEvent(wx.CommandEvent(wx.wxEVT_COMMAND_LISTBOX_SELECTED))
  196.             self.Refresh()
  197.             return True
  198.         else:
  199.             self.Refresh()
  200.             return False
  201.  
  202.  
  203.  
  204. class BlatantFirefoxRipoff(wx.Panel):
  205.     
  206.     def __init__(self, parent, viewer):
  207.         wx.Panel.__init__(self, parent)
  208.         self.viewer = viewer
  209.         find_label = wx.StaticText(self, -1, _('Find'))
  210.         self.TextControl = find_input = wx.TextCtrl(self, -1, size = (180, -1), style = wx.TE_PROCESS_ENTER)
  211.         nextbutton = self.nextbutton = UberButton(self, label = 'Next', skin = 'AppDefaults.PastButton')
  212.         prevbutton = self.prevbutton = UberButton(self, label = 'Prev', skin = 'AppDefaults.PastButton')
  213.         sz = self.Sizer = wx.BoxSizer(wx.HORIZONTAL)
  214.         sz.AddMany([
  215.             (find_label, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | ALIGN_RIGHT, 6),
  216.             (find_input, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL, 6),
  217.             (nextbutton, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | EXPAND, 6),
  218.             (prevbutton, 0, TOP | BOTTOM | LEFT | ALIGN_CENTER_VERTICAL | EXPAND, 6)])
  219.         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  220.         Bind = self.Bind
  221.         Bind(wx.EVT_PAINT, self.OnPaint)
  222.         self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
  223.         fiBind = find_input.Bind
  224.         fiBind(wx.EVT_TEXT, self.OnFindText)
  225.         fiBind(wx.EVT_KEY_DOWN, self.OnFindKey)
  226.         nextbutton.Bind(wx.EVT_BUTTON, self.OnFindText)
  227.         prevbutton.Bind((wx.EVT_BUTTON,), (lambda e: self.OnFindText(e, False)))
  228.  
  229.     
  230.     def OnFindKey(self, e):
  231.         c = e.KeyCode
  232.         if (c in (wx.WXK_RETURN, wx.WXK_F3) or c == ord('G')) and e.GetModifiers() in (wx.MOD_CMD, wx.MOD_CMD + wx.MOD_SHIFT):
  233.             self.OnFindText(forward = not e.ShiftDown())
  234.             self.TextControl.SetFocus()
  235.         else:
  236.             e.Skip()
  237.  
  238.     
  239.     def OnFindText(self, e = None, forward = True):
  240.         self.viewer.FindString(self.TextControl.Value, forward, False, True, True)
  241.  
  242.     
  243.     def OnPaint(self, event):
  244.         rect = wx.RectS(self.ClientSize)
  245.         dc = wx.BufferedPaintDC(self)
  246.         dc.Brush = wx.WHITE_BRUSH
  247.         dc.Pen = wx.Pen(wx.Color(213, 213, 213))
  248.         dc.DrawRectangleRect(rect)
  249.  
  250.  
  251.  
  252. class PastBrowserPanel(SimplePanel):
  253.     
  254.     def __init__(self, parent):
  255.         SimplePanel.__init__(self, parent, wx.FULL_REPAINT_ON_RESIZE)
  256.         self.BackgroundColour = WHITE
  257.         self.Sizer = wx.BoxSizer(HORIZONTAL)
  258.         sz = wx.BoxSizer(HORIZONTAL)
  259.         self.Sizer.Add(sz, 1, EXPAND | ALL, 3)
  260.         leftcol = wx.BoxSizer(VERTICAL)
  261.         acctcombo = self.acctcombo = UberCombo(self, value = '', skinkey = 'AppDefaults.PrefCombo')
  262.         acctcont = PrefPanel(self, acctcombo, 'Account')
  263.         leftcol.Add(acctcont, 0, EXPAND | ALL, 3)
  264.         buddylist = self.buddylist = ListOBuddies(self)
  265.         buddycont = PrefPanel(self, buddylist, 'Buddy')
  266.         leftcol.Add(buddycont, 1, EXPAND | TOPLESS, 3)
  267.         style = wx.NO_BORDER | CAL_SUNDAY_FIRST | CAL_SEQUENTIAL_MONTH_SELECTION | CAL_SHOW_HOLIDAYS
  268.         cal = self.cal = CalendarCtrl(self, -1, wx.DateTime.Now(), wx.DefaultPosition, wx.DefaultSize, style)
  269.         cal.SetForegroundColour(wx.Color(160, 160, 160))
  270.         cal.SetHolidayColours(wx.BLACK, wx.WHITE)
  271.         cal.SetHeaderColours(Color(160, 160, 160), Color(239, 239, 239))
  272.         calcont = PrefPanel(self, cal, 'Date')
  273.         leftcol.Add(calcont, 0, EXPAND | TOPLESS, 3)
  274.         sz.Add(leftcol, 0, EXPAND)
  275.         viewpanel = wx.Panel(self)
  276.         viewer = self.viewer = WebKitWindow(viewpanel)
  277.         finder = self.finder = BlatantFirefoxRipoff(viewpanel, viewer)
  278.         viewer.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
  279.         finder.TextControl.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
  280.         nav = BoxSizer(wx.HORIZONTAL)
  281.         prev = self.prev = UberButton(viewpanel, label = '<-', skin = BUTTON_SKIN)
  282.         next = self.next = UberButton(viewpanel, label = '->', skin = BUTTON_SKIN)
  283.         datelabel = wx.StaticText(viewpanel, -1, style = wx.ALIGN_CENTER | wx.ST_NO_AUTORESIZE)
  284.         datelabel.SetMinSize((140, -1))
  285.         prev.Bind((wx.EVT_BUTTON,), (lambda e: self.Flip(-1)))
  286.         next.Bind((wx.EVT_BUTTON,), (lambda e: self.Flip(1)))
  287.         nav.AddStretchSpacer(1)
  288.         nav.AddMany([
  289.             (prev, 0, wx.EXPAND | wx.ALIGN_CENTER),
  290.             (datelabel, 0, wx.EXPAND | wx.ALIGN_CENTER),
  291.             (next, 0, wx.EXPAND | wx.ALIGN_CENTER)])
  292.         nav.AddStretchSpacer(1)
  293.         viewpanel.Sizer = wx.BoxSizer(wx.VERTICAL)
  294.         viewpanel.Sizer.AddMany([
  295.             (nav, 0, EXPAND),
  296.             (viewer, 1, EXPAND),
  297.             (finder, 0, EXPAND)])
  298.         sz.Add(PrefPanel(self, viewpanel, _('Conversation Log')), 1, EXPAND | ALL, 3)
  299.         Bind = self.Bind
  300.         Bind(wx.EVT_PAINT, self.OnPaint)
  301.         
  302.         def OnAcct(*a):
  303.             buddylist.SetList(GetBuddies(acctcombo.Value.id))
  304.             OnBuddy()
  305.  
  306.         
  307.         def OnBuddy(*a):
  308.             self.dates = GetDates(buddylist.SelectedBuddy.dir)
  309.             self.next.Enable(True)
  310.             self.prev.Enable(True)
  311.             self.cal.Enable(True)
  312.             OnCalChange()
  313.  
  314.         
  315.         def OnCalChange(*a):
  316.             caldate = cal.Date
  317.             currentyear = caldate.GetYear()
  318.             currentmonth = caldate.GetMonth()
  319.             relevantdates = (None, frozenset)((lambda .0: for date in .0:
  320. if date.GetYear() == currentyear and date.GetMonth() == currentmonth and date.GetDay():
  321. date.GetDay()continue)(self.dates))
  322.             SetHoliday = cal.SetHoliday
  323.             SetAttr = cal.SetAttr
  324.             for i in xrange(1, 32):
  325.                 if i in relevantdates:
  326.                     SetHoliday(i)
  327.                     continue
  328.                 SetAttr(i, CalendarDateAttr(Color(160, 160, 160)))
  329.             
  330.             OnDayChange()
  331.  
  332.         self.OnCalChange = OnCalChange
  333.         
  334.         def OnDayChange(*a):
  335.             date = cal.Date
  336.             self.date = date
  337.             datelabel.SetLabel(date.FormatDate())
  338.             if cal.GetAttr(date.GetDay()).IsHoliday():
  339.                 logpath = logpath_for_date(buddylist.SelectedBuddy, date)
  340.                 viewer.Frozen().__enter__()
  341.                 
  342.                 try:
  343.                     viewer.SetPageSource(logpath.text('utf-8', 'replace'), logpath.url())
  344.                     viewer.RunScript('window.scroll(0, 0);')
  345.                 finally:
  346.                     pass
  347.  
  348.             else:
  349.                 year = str(date.GetYear())
  350.                 month = date.GetMonth()
  351.                 month = wx.DateTime.GetMonthName(int(month))
  352.                 day = str(date.GetDay())
  353.                 viewer.SetPageSource('There are no chat logs for %s %s, %s with %s.' % (month, day, year, buddylist.SelectedBuddy.name), 'file:///C:/')
  354.             wx.CallAfter(cal.Refresh)
  355.  
  356.         self.OnDayChange = OnDayChange
  357.         acctcombo.SetCallbacks(value = OnAcct)
  358.         buddylist.Bind(wx.EVT_LISTBOX, OnBuddy)
  359.         cBind = cal.Bind
  360.         cBind(EVT_CALENDAR_YEAR, OnCalChange)
  361.         cBind(EVT_CALENDAR_MONTH, OnCalChange)
  362.         cBind(EVT_CALENDAR_SEL_CHANGED, OnDayChange)
  363.         acctcombo.SetItems(MakeAccountItems(), 0)
  364.  
  365.     
  366.     def OnKeyDown(self, event):
  367.         KeyCode = event.KeyCode
  368.         if KeyCode == wx.WXK_PAGEDOWN:
  369.             self.viewer.ScrollPages(1)
  370.         elif KeyCode == wx.WXK_PAGEUP:
  371.             self.viewer.ScrollPages(-1)
  372.         else:
  373.             event.Skip()
  374.  
  375.     
  376.     def Flip(self, delta):
  377.         log.info('Flip(%s)', delta)
  378.         log.info(' self.dates: %r', self.dates)
  379.         dates = self.dates
  380.         date = self.date
  381.         
  382.         try:
  383.             foundIndex = dates.index(date) + delta
  384.         except ValueError:
  385.             alldates = [
  386.                 DateTimeFromDMY(1, 1, 1900)] + dates + [
  387.                 DateTimeFromDMY(20, 10, 3000)]
  388.             foundIndex = len(dates) - 1
  389.             for i in xrange(1, len(alldates)):
  390.                 if date.IsStrictlyBetween(alldates[i - 1], alldates[i]):
  391.                     foundIndex = None if delta < 0 else i
  392.                     break
  393.                     continue
  394.             
  395.  
  396.         foundIndex = max(0, min(len(dates) - 1, foundIndex))
  397.         self.cal.SetDate(dates[foundIndex])
  398.         self.OnCalChange()
  399.  
  400.     
  401.     def OnPaint(self, event):
  402.         rect = wx.RectS(self.Size)
  403.         dc = wx.PaintDC(self)
  404.         dc.Brush = WHITE_BRUSH
  405.         dc.Pen = TRANSPARENT_PEN
  406.         dc.DrawRectangleRect(rect)
  407.  
  408.     
  409.     def OpenBuddyHistory(self, acctdir, acct, name, service):
  410.         if not SelectAccountByDir(acctdir, self.acctcombo):
  411.             self.next.Enable(False)
  412.             self.prev.Enable(False)
  413.             self.cal.Enable(False)
  414.             return self.NoHistory(name, service, acct)
  415.         
  416.         
  417.         def AfterOpenBuddyHistory():
  418.             if not self.buddylist.SelectBuddy(service, name):
  419.                 self.next.Enable(False)
  420.                 self.prev.Enable(False)
  421.                 self.cal.Enable(False)
  422.                 return self.NoHistory(name, service, acct)
  423.             
  424.             self.next.Enable(True)
  425.             self.prev.Enable(True)
  426.             self.cal.Enable(True)
  427.             self.Flip(1)
  428.  
  429.         wx.CallAfter(AfterOpenBuddyHistory)
  430.  
  431.     
  432.     def NoHistory(self, name, service, acct):
  433.         self.viewer.SetPageSource('There is no chat history for %s on %s with %s.' % (name, service, acct), 'file:///C:/')
  434.  
  435.  
  436.  
  437. class PastBrowser(wx.Frame):
  438.     
  439.     def __init__(self):
  440.         wx.Frame.__init__(self, None, -1, _('Past Chat Browser'), name = 'Past Chat Browser')
  441.         self.SetFrameIcon(skin.get('appdefaults.taskbaricon'))
  442.         sz = self.Sizer = wx.BoxSizer(VERTICAL)
  443.         self.pastbrowser = PastBrowserPanel(self)
  444.         sz.Add(self.pastbrowser, 1, EXPAND)
  445.         persist_window_pos(self, defaultrect = (150, 150, 700, 500))
  446.         snap_pref(self)
  447.  
  448.     
  449.     def MakeOrShow(cls):
  450.         win = PastBrowser.RaiseExisting()
  451.         if win is None:
  452.             win = PastBrowser()
  453.             wx.CallAfter(win.Show)
  454.         
  455.         return win
  456.  
  457.     MakeOrShow = classmethod(MakeOrShow)
  458.     
  459.     def MakeOrShowAndSelect(cls, buddydir):
  460.         acctdir = buddydir.parent
  461.         acct = acctdir.name
  462.         (name, service) = buddydir.name.rsplit('_', 1)
  463.         win = cls.MakeOrShow()
  464.         win.pastbrowser.OpenBuddyHistory(acctdir, acct, name, service)
  465.  
  466.     MakeOrShowAndSelect = classmethod(MakeOrShowAndSelect)
  467.  
  468. if __name__ == '__main__':
  469.     from tests.testapp import testapp
  470.     a = testapp(username = 'aaron')
  471.     from path import path
  472.     dir = path('C:\\Users\\Aaron\\Documents\\Digsby Logs\\aaron\\digsby\\aaron@digsby.org\\mike@digsby.org_digsby')
  473.     PastBrowser.MakeOrShowAndSelect(dir)
  474.     a.MainLoop()
  475.  
  476.